from django.shortcuts import render,redirect
#导包
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
from django.utils.decorators import method_decorator
from myapp.myser import *
#导入类视图
from django.views import View

from myapp.models import User
import json
from django.core.serializers import serialize
from rest_framework.response import Response
from rest_framework.views import APIView
#导入加密库
import hashlib
#导入图片库
#绘画库
from PIL import ImageDraw
#字体库
from PIL import ImageFont
#图片库
from PIL import Image
#随机库
import random
#文件流
import io

import requests

#导入上传文件夹配置
from mydjango.settings import UPLOAD_ROOT
import os

#导入原生sql模块
from django.db import connection

import jwt

#导入redis数据库
import redis

#导入时间模块
import time

#导入公共目录变量
from mydjango.settings import BASE_DIR

#导包
from django.db.models import Q,F

#导入dwebsocket的库
from dwebsocket.decorators import accept_websocket
import uuid

from PIL import Image,ImageDraw

 # 导包
import redis

  # 定义IP地址和端口
host = '127.0.0.1'
port = 6379
  # 链接对象
r = redis.Redis(host=host,port=port)

from django.utils.deprecation import MiddlewareMixin

  # 自定义中间件
class MyMiddleware(MiddlewareMixin):
    # 请求之前
    def process_request(self,request):
        # uid = request.GET.get('uid')
        # cline_jwt = request.GET.get('jwt',None)
        # if cline_jwt == None:
        #     return HttpResponse('您没有带上令牌')
        #
        # print(uid)
        #
        # decode_jwt = jwt.decode(cline_jwt, '123', algorithms=['HS256'])
        # if decode_jwt['uid'] != str(uid):
        #     return HttpResponse('您篡改了用户id')

        # return HttpResponse('您篡改了用户id')
            pass
    # 模板渲染之前
    def process_view(self,request,view_func,view_args,view_kwargs):
        pass
    # 请求之后
    def process_response(self,request,response):
        return response

  # 定义装饰器
def my_decorator(func):
    def wrapper(request,*args,**kwargs):
        # print('装饰器')
        # print('请求接口是%s' % request.path)
        #
        # # 判断jwt逻辑
        # uid = request.GET.get('uid')
        # cline_jwt = request.GET.get('jwt',None)
        #
        # decode_jwt = jwt.decode(cline_jwt, '123', algorithms=['HS256'])
        # if decode_jwt['uid'] != str(uid):
        #     return HttpResponse('您篡改了用户id')
        return func(request,*args,**kwargs)
    return wrapper

# 用户信息类
class UserInfo(APIView):
    # 导入装饰器
    @method_decorator(my_decorator)
    def get(self, request):
        uid = request.GET.get("uid")

        # 查询数据
        user = User.objects.get(id=int(uid))

        # 序列化对象
        user_ser = Userser(user)

        return Response(user_ser.data)
        

# 七牛云密钥接口
from qiniu import Auth

class QiNiu(APIView):
    def get(self,request):
        # 声明密钥对象
        q = Auth('Xhm0gJwxb7tppghoHulMB-pb7tuRKg8b7zAe4cEf','HCTVbbhpMaDR9Ef0gWWp3LDH4QfbWwig3CnaTEy0')
        # 生成令牌
        token = q.upload_token('lianghaochen')

        return Response({'uptoken':token})

    # 更新用户头像
class AlterImg(APIView):
    def get(self, request):
        # 获取数据
        uid = request.GET.get('uid')
        img = request.GET.get('img')
        # 查询修改的用户
        user = User.objects.get(id=int(uid))
        if user:
            # 修改头像
            user.img = img
            user.save()
            return Response({
                'code': 200,
                'message': '修改用户头像成功'
            })

# 用户密码更新接口
class UpdatePassword(APIView):
    def get(self,request):

        # 接收参数
        uid = request.GET.get('uid')
        password = request.GET.get('password')

        # 查询修改用户
        user = User.objects.get(id=int(uid))

        # 保存新密码
        user.password = make_password(password)
        user.save()

        return Response({'message':'修改成功'})

  # 定义上传视图类
class UploadFile(View):
    def post(self,request):
        # 接收参数
        img = request.FILES.get('file')

        # 建立文件流对象
        f = open(os.path.join(UPLOAD_ROOT,'',img.name),'wb')

        # 写入服务器端
        for chunk in img.chunks():
            f.write(chunk)
        f.close()

        # 打开图片
        im = Image.open('./static/upload/'+img.name)
        # 生成画笔对象
        draw = ImageDraw.Draw(im)
        # 修改图片
        draw.text((0, 0), '1906', fill=(76, 234, 124, 180))

        # 存储图片
        im.save('./static/upload/'+img.name)

        # 返回文件名
        return HttpResponse(json.dumps({'filename':img.name},ensure_ascii=
                                       False),content_type='application/json')

import time
import hmac
import base64
from hashlib import sha256
import urllib

#构造钉钉回调方法
def ding_back(request):

    #获取code
    code = request.GET.get("code")

    t = time.time()
    #时间戳
    timestamp = str((int(round(t * 1000))))
    appSecret ='ly-AzMKMmCKQP3geaILT_An32kEfKO3HeOtApy5CgKwjytevVZC0WYsT2gxMB160'
    #构造签名
    signature = base64.b64encode(hmac.new(appSecret.encode('utf-8'),timestamp.encode('utf-8'), digestmod=sha256).digest())
    #请求接口，换取钉钉用户名
    payload = {'tmp_auth_code':code}
    headers = {'Content-Type': 'application/json'}
    res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature='+urllib.parse.quote(signature.decode("utf-8"))+"&timestamp="+timestamp+"&accessKey=dingoaukgkwqknzjvamdqh",data=json.dumps(payload),headers=headers)

    res_dict = json.loads(res.text)
    # print(res_dict)
    # return HttpResponse(res.text)

    # 判断是否用钉钉登录过
    user = User.objects.filter(username=str(res_dict['user_info']['nick'])).first()

    ding_id = ''
    user_id = ''

    if user:
        # 代表曾经登录过
        ding_id = user.username
        user_id = user.id
    else:
        # 自动创建账号
        user = User(username=str(res_dict['user_info']['nick']),password='',type=0)
        # 保存
        user.save()

        # 查询用户id
        user = User.objects.filter(username=str(res_dict['user_info']['nick'])).first()

        ding_id = str(res_dict['user_info']['nick'])
        user_id = user.id
    # 跳转操作
    return redirect("http://localhost:8080/?dduser=" + str(ding_id) + '&uid=' + str(user_id))


# 新浪微博回调视图
def weibo_back(request):
    # 获取code
    code = request.GET.get('code')

    # 换取网址
    access_token_url = "https://api.weibo.com/oauth2/access_token"

    # 发送请求进行换取
    res = requests.post(
        access_token_url,
        data={
            # app_id应用id
            "client_id": '543875374',
            # app_secret密钥
            "client_secret": "84791387ef015bb4ad3d75425ed30c00",
            # 授权类型code
            "grant_type": "authorization_code",
            # code参数
            "code": code,
            # 回调网址
            "redirect_uri": "http://127.0.0.1:8000/md_admin/weibo"
        }
    )
   # 转换类型
    res = json.loads(res.text)

    # 换取新浪微博昵称 json
    result = requests.get('https://api.weibo.com/2/users/show.json',params=
        {'access_token':res['access_token'],'uid':res['uid']})

    result = json.loads(result.text)

    # 判断该用户是否曾经登录过
    user = User.objects.filter(username=str(result['name'])).first()

    sina_id = ''
    user_id = ''

    if user:
        sina_id = user.username
        user_id = user.id
    else:
        # 手动创建一个账号
        user = User(username=str(result['name']),password='')
        user.save()

        sina_id = result['name']

        # 查询一下刚入库的新账号id
        user = User.objects.filter(username=str(result['name'])).first()
        user_id = user.id

    return redirect('http://localhost:8080?sina_id='+sina_id+'&uid='+str(user_id))

    # return HttpResponse(result['name'])


  # 登录接口
class Login(APIView):
    def get(self,request):
        # 接收参数
        username = request.GET.get('username','null')
        password = request.GET.get('password','null')

        # 查询数据
        user = User.objects.filter(username=username,password=make_password(password)).first()

        if user:
            res = {}
            res['code'] = 200
            res['message'] = '登录成功'
            res['username'] = user.username
            res['uid'] = user.id
            # 加入jwt令牌机制
            # 进行编码
            encode_jwt = jwt.encode({'uid': str(user.id)}, '123', algorithm='HS256')

            # 解码操作
            # 强转
            encode_str = str(encode_jwt, 'utf-8')

            res['jwt'] = encode_str

            return Response(res)
        else:
            res = {}
            res['code'] = 405
            res['message'] = '你的用户名或者密码错误'
            return Response(res)

# 定义验证码
class MyCode(View):
    # 定义随机验证颜色
    def get_random_color(self):
        R = random.randrange(255)
        G = random.randrange(255)
        B = random.randrange(255)
        return (R, G, B)

    # 随机验证码
    def get(self, request):
        # 画布
        img_size = (110, 50)
        # 定义颜色类型
        image = Image.new("RGB", img_size, 'white')
        # 画笔
        draw = ImageDraw.Draw(image, 'RGB')
        # 定义随机字符串
        source = '0123456789'
        # 容器，用来接收随机字符串
        code_str = ''
        # 定义字体
        # my_font = ImageFont.truetype(font="c:\\Windows\\Fonts\\STHUPO.TTF", size=15)
        for i in range(4):
            # 获取字体颜色
            text_color = self.get_random_color()
            # 获取字符串
            tmp_num = random.randrange(len(source))
            # 获取字符集
            random_str = source[tmp_num]
            # 添加到容器中
            code_str += random_str
            # 绘制
            draw.text((10 + 30 * i, 20), random_str, text_color)
        # 文件流缓冲区
        buf = io.BytesIO()

        # 将随机码存储到redis中
        # r.set('code', code_str)
        # 将验证码存储到session中
        request.session['code'] = code_str
        print(request.session['code'])
        # 将图片保存到缓冲区
        image.save(buf, 'png')

        return HttpResponse(buf.getvalue(), 'image/png')

# md5加密方法
def make_password(mypass):
    # 生成MD5对象
    md5 = hashlib.md5()
    # 定义机密对象
    sign_str = str(mypass)
    # 转码
    sign_utf8 = sign_str.encode(encoding='utf-8')
    # 加密
    md5.update(sign_utf8)
    # 生成密钥串
    md5_server = md5.hexdigest()

    return md5_server

  # 注册模块
class Register(APIView):
    def get(self,request):
        # 接收参数
        username = request.GET.get('username','null')
        password = request.GET.get('password','null')
        code = request.GET.get('code','null')

        # 从session中获取验证码
        session_code = request.session.get('code')

        print(session_code)

        # 从redis获取验证码
        # redis_code = r.get('code')
        # redis_code = redis_code.decode('utf-8')
        # print(redis_code)

        # 判断验证码是否正确
        if code != session_code:
            res = {}
            res['code'] = 405
            res['message'] = '验证码输入错误'
            return Response(res)

        # 排重
        user = User.objects.filter(username=username).first()

        if user:
            res = {}
            res['code'] = 405
            res['message'] = '该用户名已存在'
            return Response(res)
        # 入库
        user = User(username=username,password=make_password(password))
        user.save()

        res = {}
        res['code'] = 200
        res['message'] = '注册成功'

        return Response(res)
